home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / network / ka9q / ka9q_src.arc / PATHNAME.C < prev    next >
C/C++ Source or Header  |  1988-07-28  |  3KB  |  118 lines

  1. #include "global.h"
  2.  
  3. /* Given a working directory and an arbitrary pathname, resolve them into
  4.  * an absolute pathname. Memory is allocated for the result, which
  5.  * the caller must free
  6.  */
  7. char *
  8. pathname(cd,path)
  9. char *cd;    /* Current working directory */
  10. char *path;    /* Pathname argument */
  11. {
  12.     register char *buf,*cp;
  13.     char *cdtmp,*pathtmp;
  14.  
  15.     if(cd == NULLCHAR || path == NULLCHAR)
  16.         return NULLCHAR;
  17. #if    (MSDOS || ATARI_ST)
  18.     /* Make temporary copies of cd and path
  19.      * with all \'s translated to /'s
  20.     */
  21.     pathtmp = malloc((unsigned)strlen(path)+1);
  22.     strcpy(pathtmp,path);
  23.     path = pathtmp;
  24.     if((cp = path) != NULLCHAR){
  25.         while((cp = index(cp,'\\')) != NULLCHAR)
  26.             *cp = '/';
  27.     }
  28.     cdtmp = malloc((unsigned)strlen(cd)+1);
  29.     strcpy(cdtmp,cd);
  30.     cd = cdtmp;
  31.     if((cp = cd) != NULLCHAR){
  32.         while((cp = index(cp,'\\')) != NULLCHAR)
  33.             *cp = '/';
  34.     }
  35. #endif
  36.     /* Strip any leading white space on args */
  37.     while(*cd == ' ' || *cd == '\t')
  38.         cd++;
  39.     while(*path == ' ' || *path == '\t')
  40.         path++;
  41.  
  42.     /* Allocate and initialize output buffer; user must free */
  43.     buf = malloc((unsigned)strlen(cd) + strlen(path) + 10); /* fudge factor */
  44.     buf[0] = '\0';
  45.  
  46.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  47.     if(path[0] != '/')
  48.         crunch(buf,cd);
  49.  
  50.     crunch(buf,path);
  51.  
  52.     /* Special case: null final path means the root directory */
  53.     if(buf[0] == '\0'){
  54.         buf[0] = '/';
  55.         buf[1] = '\0';
  56.     }
  57.  
  58. #if    (MSDOS || ATARI_ST)
  59.     /* Translate all /'s back to \'s and free temp copies of args */
  60.     if((cp = buf) != NULLCHAR){
  61.         while((cp = index(cp,'/')) != NULLCHAR)
  62.             *cp = '\\';
  63.     }
  64.     free(cdtmp);
  65.     free(pathtmp);
  66. #endif
  67.     return buf;
  68. }
  69.  
  70. /* Process a path name string, starting with and adding to
  71.  * the existing buffer
  72.  */
  73. static
  74. crunch(buf,path)
  75. char *buf;
  76. register char *path;
  77. {
  78.     register char *cp;
  79.     
  80.  
  81.     cp = buf + strlen(buf); /* Start write at end of current buffer */
  82.     
  83.     /* Now start crunching the pathname argument */
  84.     for(;;){
  85.         /* Strip leading /'s; one will be written later */
  86.         while(*path == '/')
  87.             path++;
  88.         if(*path == '\0')
  89.             break;        /* no more, all done */
  90.         /* Look for parent directory references, either at the end
  91.          * of the path or imbedded in it
  92.          */
  93.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  94.             /* Hop up a level */
  95.             if((cp = rindex(buf,'/')) == NULLCHAR)
  96.                 cp = buf;    /* Don't back up beyond root */
  97.             *cp = '\0';        /* In case there's another .. */
  98.             path += 2;        /* Skip ".." */
  99.             while(*path == '/')    /* Skip one or more slashes */
  100.                 path++;
  101.         /* Look for current directory references, either at the end
  102.          * of the path or imbedded in it
  103.          */
  104.         } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  105.             /* "no op" */
  106.             path++;         /* Skip "." */
  107.             while(*path == '/')    /* Skip one or more slashes */
  108.                 path++;
  109.         } else {
  110.             /* Ordinary name, copy up to next '/' or end of path */
  111.             *cp++ = '/';
  112.             while(*path != '/' && *path != '\0')
  113.                 *cp++ = *path++;
  114.         }
  115.     }
  116.     *cp++ = '\0';
  117. }
  118.